package top.hmtools.dictionary;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import top.hmtools.beans.DivisionBean;
import top.hmtools.enums.EDataVersion;
import top.hmtools.exception.InvalidCodeException;

/**
 * 行政区域字典
 * 
 * @author Jianghaibo
 * 
 */
public class Dictionary {

	/**
	 * 静态字典
	 */
	private static Map<String, DivisionBean> DICTIONARIES = new HashMap<String, DivisionBean>();

	/**
	 * 临时原始数据字典（省）
	 */
	private static Map<String, String> temp_dict_province = new HashMap<String, String>();

	/**
	 * 临时原始数据字典（市）
	 */
	private static Map<String, String> temp_dict_city = new HashMap<String, String>();

	/**
	 * 临时原始数据字典（区/县）
	 */
	private static Map<String, String> temp_dict_district = new HashMap<String, String>();
	
	private static List<DivisionBean> DIVISIONBEANS = new ArrayList<DivisionBean>();
	
	/**
	 * 初始化当前最新数据版本
	 */
	public static void init(){
		init(EDataVersion.getLast());
	}
	
	/**
	 * 根据版本信息初始化
	 * @param dataVersion
	 */
	public static void init(EDataVersion dataVersion){
		InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("datas/"+dataVersion);
		init(inputStream);
	}

	/**
	 * 初始化字典
	 * 
	 * @param inputStream
	 */
	public static void init(InputStream inputStream) {
		BufferedReader rr = new BufferedReader(new InputStreamReader(
				inputStream));
		try {
			while (rr.ready()) {
				String line = rr.readLine();
				String[] split = null;
				if(line.contains(",")){
					split = line.split(",");
				}else if(line.contains("\t")){
					split = line.split("\t");
				}
				String code = split[0].trim();
				String name = split[1].trim();

				// 省
				if (code.endsWith("0000")) {
					temp_dict_province.put(code, name);
				} else if (code.endsWith("00") && !code.endsWith("0000")) {
					temp_dict_city.put(code, name);
				} else {
					temp_dict_district.put(code, name);
				}
			}

			// 省
			for (Entry<String, String> item : temp_dict_province.entrySet()) {
				addData(item.getKey(), item.getValue());
			}

			// 市
			for (Entry<String, String> item : temp_dict_city.entrySet()) {
				addData(item.getKey(), item.getValue());
			}

			// 区/县
			for (Entry<String, String> item : temp_dict_district.entrySet()) {
				addData(item.getKey(), item.getValue());
			}

			Collections.sort(DIVISIONBEANS, new Comparator<DivisionBean>() {

				public int compare(DivisionBean aaa, DivisionBean bbb) {
					return Integer.valueOf(aaa.getCode())-Integer.valueOf(bbb.getCode());
				}
			});
		} catch (IOException e) {
			System.err.println("Error in loading GB2260 data!");
			throw new RuntimeException(e);
		}
	}

	/**
	 * 添加内容到字典
	 * 
	 * @param code
	 * @param name
	 */
	public static void addData(String code, String name) {
		try {
			if (code.length() != 6) {
				throw new InvalidCodeException("Invalid code");
			}

			DivisionBean divisionBean = new DivisionBean();
			divisionBean.setCode(code);

			// 省、直辖市
			boolean isProvince = code.endsWith("0000");
			if (isProvince) {
				divisionBean.setProvince(name);
				DICTIONARIES.put(divisionBean.getCode(), divisionBean);
				DIVISIONBEANS.add(divisionBean);
				return;
			}

			String provinceCode = code.substring(0, 2) + "0000";
			String provinceName = temp_dict_province.get(provinceCode);
			divisionBean.setProvince(provinceName);

			// 地级市
			boolean isCity = code.endsWith("00") && !code.endsWith("0000");
			if (isCity) {
				divisionBean.setCity(name);
				divisionBean.setParentCode(provinceCode);
				DICTIONARIES.get(provinceCode).addChildren(divisionBean);// 添加到所在省信息的子节点集中
				DIVISIONBEANS.add(divisionBean);
				return;
			}

			String cityCode = code.substring(0, 4) + "00";
			String cityName = temp_dict_city.get(cityCode);// 直辖市下的区县以及省直属的县，结果是null
			divisionBean.setCity(cityName);

			// 区、县、县级市
			divisionBean.setDistrict(name);
			Map<String, DivisionBean> cities = DICTIONARIES.get(provinceCode)
					.getChildren();
			if (cityName == null || "".equals(cityName)) {// 直辖市下的区以及直接归省管辖的县
				divisionBean.setParentCode(provinceCode);
				DICTIONARIES.get(provinceCode).addChildren(divisionBean);
			} else {
				divisionBean.setParentCode(cityCode);
				cities.get(cityCode).addChildren(divisionBean);
			}
			DIVISIONBEANS.add(divisionBean);
		} catch (Exception e) {
			System.out.println("add " + code + "(" + name + ")" + " fail : "
					+ e.getMessage());
		}
	}

	/**
	 * 根据代号获取行政地区信息
	 * 
	 * @param code
	 * @return
	 */
	public static DivisionBean getByCode(String code) {
		if (code == null || "".equals(code)) {
			return null;
		}

		if (code.length() != 6) {
			return null;
		}
		try {
			// 省
			if (code.endsWith("0000")) {
				return DICTIONARIES.get(code);
			}

			// 市
			String provinceCode = code.substring(0, 2) + "0000";
			if (code.endsWith("00") && !code.endsWith("0000")) {
				return DICTIONARIES.get(provinceCode).getChildren().get(code);
			}

			// 区/县
			String cityCode = code.subSequence(0, 4) + "00";
			if(temp_dict_city.containsKey(cityCode)){
				return DICTIONARIES.get(provinceCode).getChildren().get(cityCode)	.getChildren().get(code);
			}else{
				return DICTIONARIES.get(provinceCode).getChildren().get(code);
			}

		} catch (Exception e) {
			System.out	.println("get DivisionBean info fail : " + e.getMessage());
			return null;
		}
	}
	
	/**
	 * 获取所有行政地区信息
	 * @return
	 */
	public static List<DivisionBean> getAll(){
		List<DivisionBean> result = new ArrayList<DivisionBean>();
		result.addAll(DIVISIONBEANS);
		return result;
	}
	
	/**
	 * 获取所有的省份信息
	* <br>方法说明：                    getAllProvince
	* <br>输入参数说明：           
	* <br>@return
	* <br>输出参数说明：
	* <br>List<DivisionBean>           
	*
	 */
	public static List<DivisionBean> getAllProvince(){
	    List<DivisionBean> result = new ArrayList<DivisionBean>();
	    result.addAll(DICTIONARIES.values());
	    return result;
	}

}
